/*
 * agent.c
 *
 *  Created on: Feb 12, 2012
 *      Author: jiabin
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>

#include "splitter.h"
#include "secure_rw.h"
#include "auth.h"

int file_fd;

void error(const char *msg)
{
	perror(msg);
	exit(1);
}

int sockfd;

void sighandler(int i)
{
	close(sockfd);
	exit(0);
}

int agent_main(int portno, int index)
{
	signal(SIGINT, &sighandler);
	srand(time(0));

	char cert_file[16];
	char key_file[16];

	sprintf(cert_file, "agent%d_cert.pem", index);
	sprintf(key_file, "agent%d_key.pem", index);

	socklen_t clilen;
	char buffer[MAX_READ];
	struct sockaddr_in serv_addr, cli_addr;
	int n;

	struct connection conn;
	conn.seq = 1;
	//conn.secret = (unsigned char *) "abcdefghijklmnop";
	//conn.iv = (unsigned char *) "0123456789abcdef";

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0)
		error("ERROR opening socket");
	bzero((char *) &serv_addr, sizeof(serv_addr));

	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);
	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		error("ERROR on binding");
	listen(sockfd, 1);
	clilen = sizeof(cli_addr);
	conn.sockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
	if (conn.sockfd < 0)
		error("ERROR on accept");

	if (auth_passive(&conn, cert_file, key_file, "Client", FALSE) < 0)
		return -1;

	while (1)
	{
		bzero(buffer, MAX_READ);
		n = sc_read(&conn, buffer, MAX_READ);
		if (n < 0)
			error("ERROR reading from socket");

		n = write(1, buffer, n);
		if (n < 0)
			error("ERROR writing to socket");
	}

	close(file_fd);
	close(sockfd);
	close(conn.sockfd);
	return 0;
}
